<?php

namespace app\common\service;

abstract class AbstractService
{

    private $_isSuccess = true;
    private $_isWarning = false;
    /**
     * 错误代码
     * @var unknown
     */
    public $errorCode = null;

    public $lang = null;
    public $lang_language = null;   #语言包

    /**
     * 错误信息
     * @var unknown
     */
    public $errorMessage = null;

    /**
     * 提示信息
     * @var unknown
     */
    public $message = null;


    public $sensitiveSuffix = '_sensitive';

    /**
     * 数据
     * @var unknown
     */
    public $datas = [];

    public function __construct(){
        $this->_init();
    }

    /**
     * 析构函数，主要处理命令行执行，静态属性没有及时清除会遗留给下一个执行程序
     * @throws \ReflectionException
     */
    public function __destruct()
    {
        if (is_cli()) {
            $classRef = new \ReflectionClass($this);
            $static_properties = $classRef->getStaticProperties();
            foreach ($static_properties as $property_name => $property_value) {
                if (is_array($property_value))
                    $classRef->setStaticPropertyValue($property_name, []);
            }
        }

    }



    public $currentPlatFormServiceMatch;

    protected function _init()
    {

    }

    private static $_models = array();



    /**
     * @author xx
     * @Date 2023/4/24 15:01
     * @return static
     */
    public static function staticModel(){
        return new static();
        $class_name_key = md5(get_called_class());
        if (isset(self::$_models[$class_name_key]))
            return self::$_models[$class_name_key];

        self::$_models[$class_name_key] = new static();
        return self::$_models[$class_name_key];
    }




    public function get_platform_obj($code ,$className ,$file_code ='' ,$ext_path='') {
        ####获取code映射modules_code
        $code = strtoupper($code);
        $isUseFileCode = $this->fileCodePlatformMap[$code] ?? 0;
        $platform_code_modules = $this->lang->language['platform_code_modules'];

        $code = $platform_code_modules[$code] ?? $code;
        $className = $code.'_'.$className;
        $code = $isUseFileCode && $file_code ? $file_code : $code;
        $ext_path = !$isUseFileCode && $file_code ? $file_code : $ext_path;
        if($ext_path) $className = trim($ext_path,'\\').'\\'.$className;

        $classPath = sprintf($this->currentPlatFormServiceMatch ,$code ,$className);
        if (!class_exists($classPath)) throw new \RuntimeException('服务文件未找到，请检查文件 '.$classPath);

        if (is_callable([$classPath ,'static_model'])) {
            return $classPath::static_model();
        }
        return $classPath::staticModel();
    }

    /**
     * 定义生成redis缓存key
     * @author cyz-andy
     * @Date 2021/1/21 19:49
     * @param $mark
     * @param $fun //对应的调用方法名称
     * @return string
     */
    public static function getCacheKey($mark,$fun){

        $original_class = trim(get_called_class(),'\\');   #原始调用类
        if (strrpos($original_class,'\\') !== false) $original_class = str_replace("\\",'.',$original_class);

        //为空取org_code
        $mark = $mark ? : '';
        return $original_class.'.'.strtolower($fun).'_'.$mark;
    }


    /**
     * 组装封装返回数组格式数据
     * @author cyz-andy
     * @Date 2021/5/27 15:53
     * @param array $data
     * @return array
     */
    public function format_id_value($data = array(),$value_key='',$id_key='',$id_is_value=false){

        if(!is_array($data) || empty($data)){
            return array();
        }
        $ret_arr = array();
        $i = 0;
        foreach ($data as $k => $v){
            $ret_arr[$i]['id'] = $k;
            $id_is_value && $ret_arr[$i]['id'] = $v;
            if (is_array($v)){
                $ret_arr[$i] = $v;
                ($value_key && isset($v[$value_key])) && $ret_arr[$i]['value'] = $v[$value_key];
                ($id_key && isset($v[$id_key])) && $ret_arr[$i]['id'] = $v[$id_key];

            }else{
                $ret_arr[$i]['value'] = $v;
            }
            $i ++;
        }
        return $ret_arr;
    }

    /**
     * @desc 递归返回value格式数据
     * @Author BlueStorm
     * @Date 2021/6/15 20:46
     * @param $data
     * @param string $value_key
     * @param string $sub_name
     * @return array
     */
    public function format_value(&$data, $value_key = 'name', $sub_name = 'children')
    {
        if(empty($data) || !is_array($data)){
            return [];
        }
        foreach ($data as $key => &$value){

            if(isset($value[$value_key]) && !empty($value[$value_key])){
                $value['value'] = $value[$value_key];
            }

            if(!empty($value[$sub_name]) && is_array($value[$sub_name])){
                $this->format_value($value[$sub_name],$value_key,$sub_name);
            }
        }
        return $data;
    }

    /**
     * @desc 递归返回简洁value格式数据
     * @Author BlueStorm
     * @Date 2021/6/17 13:37
     * @param $data
     * @param string $value_key
     * @param string $sub_name
     * @return array
     */
    public function concise_value(&$data, $value_key = 'name', $sub_name = 'children')
    {
        if(empty($data) || !is_array($data)){
            return [];
        }
        foreach ($data as $key => &$value){
            if(isset($value[$value_key]) && !empty($value[$value_key])){
                $value['value'] = $value[$value_key];
            }
            foreach ($value as $k => $v){
                if($k == 'id' || $k == $sub_name || $k == 'value' || $k == 'hasChildren'){
                    continue;
                }
                unset($value[$k]);
            }
            if(!empty($value[$sub_name]) && is_array($value[$sub_name])){
                $this->concise_value($value[$sub_name]);
            }
        }
        return $data;
    }


    /**
     * 获取model字段和params之间的交集
     * @param \MY_Model $model
     * @param array $params
     * @return array
     */
    public function get_model_columns_params($model, $params)
    {
        if (!$model instanceof \MY_Model) {
            throw new \RuntimeException('$model 不是 MY_Model实例');
        }
        $schemas = $model->getMetaData();
        $columns = array_keys($schemas->columns);
        return array_filter($params, function ($key) use ($columns) {
            return in_array($key, $columns);
        }, ARRAY_FILTER_USE_KEY);
    }

    /**
     * 获取指定字段的params
     * @param array|string $model
     * @param array $params
     * @return array
     */
    public function get_params_by_name($name, $params)
    {
        return array_filter($params, function ($key) use ($name) {
            return in_array($key, $name);
        }, ARRAY_FILTER_USE_KEY);
    }

}